package com.audible.library.view.controller;

import com.audible.library.constants.Constants;
import com.audible.library.database.UserAudioBookRatingFacade;
import com.audible.library.database.UserProfileFacade;
import com.audible.library.domain.beans.UserAudioBook;
import com.audible.library.domain.beans.UserAudioBookRating;
import com.audible.library.domain.beans.UserProfile;
import com.audible.library.session.UserSession;
import com.audible.library.view.backing.PurchasedAudioBook;
import com.audible.library.view.backing.RateReview;
import com.audible.library.view.backing.UserInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;

import javax.ejb.EJB;

/**
 * The servlet class is responsible for serving users' requests on My Library page.
 * In MVC pattern, this class behaves as a controller. Ideally, we should be using
 * JSF and built in controller functionality, but we are making it simple here for
 * demo purpose.
 *
 * The class is responsible for getting list of audio books purchased by the logged in user.
 * Once the data is retrieved via domain beans, it will create the corresponding view beans
 * and copy necessary data from domain beans to view beans. The final set of data
 * will be saved in user's session to be presented on JSP/XHTML.
 *
 * @author Jigar Shah
 * @version 0.1
 */
@WebServlet(name = "LibraryController", urlPatterns = {"/LibraryController"})
public class LibraryController extends HttpServlet {
    
    private static final long serialVersionUID = 5856904128063865518L;

    @EJB
    private UserProfileFacade userProfileFacade;

    @EJB
    private UserAudioBookRatingFacade ratingFacade;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

//        response.setContentType("text/html;charset=UTF-8");
//        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession();
        UserSession userSession = (UserSession) session.getAttribute(Constants.USER_SESSION);

        // UserSession should never be null if user is logged in... but creating it for testing purpose.
        if (userSession == null)
            userSession = new UserSession();

        if (userSession == null) {
            // redirect user to the login page
        } else {

            //out.println("Starting to process...");
            UserInfo user = userSession.getUserInfo();

            // User should never be null if user is logged in... but creating it for testing purpose.
            if (user == null) {
                user = new UserInfo();
            }

            List<PurchasedAudioBook> purchasedList = new ArrayList<PurchasedAudioBook>();

            // Find the user information
            UserProfile userProfile = userProfileFacade.find(userSession.getUserID());
            //out.println(userProfile.getFirstName());
            
            // Get all the books purchased by this user and put it in the session.
            Collection<UserAudioBook> books = userProfile.getUserAudioBookCollection();

            // Iterate through the domain beans and create new view beans with required information.
            // We could technically use the domain beans for viewing purpose on JSP/JSF, but that is not a good idea.
            Iterator iter = books.iterator();
            while (iter.hasNext()) {

                UserAudioBook audioBook = (UserAudioBook) iter.next();

                PurchasedAudioBook mybook = new PurchasedAudioBook();
                mybook.setAuthor(audioBook.getAudioBook().getAuthor());

                String formatType = audioBook.getAudioBook().getFormat();
                // Based on the format type set the correct viewable format type... switch statement
                // mybook.setFormatType(PurchasedAudioBook.Format.Format4);

                // Set other fields in view beans accordingly.

                // Find out the rating/review for each book that user owns
                UserAudioBookRating rating = ratingFacade.findRatingsByUserBook(userSession.getUserID(), audioBook.getUserAudioBookPK().getAudioBookId());
                // Once we get the rating from the database, we can prepare the view bean
                RateReview review = new RateReview();
                // Now copy necesary data from domain bean to view bean here...

                mybook.setRateReview(review);

                purchasedList.add(mybook);
            }
            // The ideal way would be clear out the existing list and add the books again to avoid unnecessary objects creation, but again this is just a demo.
            user.setPurchasedAudioBooks(purchasedList);
        }

        // Forward the request to my library page, which will show all the books purchaed by this user.
        RequestDispatcher dispatcher = request.getRequestDispatcher("/mylibrary.xhtml");
        dispatcher.forward(request, response);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "MyLibrary Controller";
    }// </editor-fold>
}
